package com.sky.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.SetmealDish;
import com.sky.entity.Setmeal;
import com.sky.exception.BaseException;
import com.sky.exception.DisableSetmealDishException;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.service.SetmealService;
import com.sky.mapper.SetmealMapper;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import com.sky.vo.pageResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * @author Morpeko
 * @description 针对表【setmeal(套餐)】的数据库操作Service实现
 * @createDate 2024-08-08 20:26:33
 */
@Service
@Slf4j
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private DishMapper dishMapper;

    /**
     * 套餐条件分页查询
     *
     * @param setmealPageQueryDTO
     * @return
     */
    @Override
    public pageResultVO<SetmealVO> pageSetmeal(SetmealPageQueryDTO setmealPageQueryDTO) {
        //设置分页查询参数,排序规则
        PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize(), "create_time desc");
        //创建用于分页查询的Setmeal对象
        Setmeal setmeal = new Setmeal().builder()
                .name(setmealPageQueryDTO.getName())
                .categoryId(setmealPageQueryDTO.getCategoryId())
                .status(setmealPageQueryDTO.getStatus())
                .build();
        //业务实现:条件分页查询套餐信息
        Page<SetmealVO> setmealPage = setmealMapper.pageQuerySetmeal(setmeal);
        //封装分页查询结果到vo对象
        pageResultVO<SetmealVO> pageResultVO = new pageResultVO<>();
        pageResultVO.setTotal(setmealPage.getTotal());//总记录数
        pageResultVO.setRecords(setmealPage.getResult());//分页查询结果列表
        return pageResultVO;
    }

    /**
     * 新增套餐信息
     *
     * @param setmealDTO
     */
    @Override
    public void saveSetmeal(SetmealDTO setmealDTO) {
        //创建用于新增的Setmeal对象
        Setmeal setmeal = new Setmeal().builder()
                .id(setmealDTO.getId())
                .name(setmealDTO.getName())
                .categoryId(setmealDTO.getCategoryId())
                .status(setmealDTO.getStatus())
                .image(setmealDTO.getImage())
                .description(setmealDTO.getDescription())
                .price(setmealDTO.getPrice())
                .build();
        //获取套餐果蔬信息列表
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();//获取套餐果蔬信息列表

        //业务实现:新增套餐信息
        setmealMapper.insertSetmeal(setmeal);//把insert生成的主键id赋值给setmeal对象

        if (setmealDishes != null && setmealDishes.size() > 0) {
            //业务实现:新增套餐果蔬信息
            setmealDishes.forEach(setmealDish -> {
                setmealDish.setSetmealId(setmeal.getId());
                setmealMapper.insertSetmealDish(setmealDish);
            });
        }

    }

    /**
     * 根据ids删除/批量删除套餐信息
     *
     * @param ids 注意<br>
     *            起售状态的套餐不能删除<br>
     */

    @Override
    @Transactional//多表关联操作,需要事务控制
    public void deleteSetmeal(List<Long> ids) {
        //判断套餐是否为起售状态
        //1.根据ids查询起售状态的套餐信息
        List<Setmeal> setmealList = setmealMapper.selectOnSetmealByIds(ids);
        if (setmealList != null && setmealList.size() > 0) {
            throw new BaseException(MessageConstant.SETMEAL_ON_SALE);//起售中的套餐不能删除
        }
        //业务实现:删除套餐信息-->删除套餐果蔬信息及其关联的套餐果蔬信息

        if (ids != null && ids.size() > 0) {
            //业务实现1.删除套餐信息
            setmealMapper.deleteSetmeal(ids);
            //业务实现2.删除套餐果蔬信息
            setmealMapper.deleteSetmealDish(ids);
        }

    }

    /**
     * 更新套餐状态<br>
     * 1.起售套餐时，判断套餐内是否有停售果蔬，有停售果蔬提示"套餐内包含未启售果蔬，无法启售"
     * <br>
     * 2.可以对状态为起售的套餐进行停售操作，可以对状态为停售的套餐进行起售操作
     *
     * @param status
     * @param id
     */
    @Override
    public void updateSetmealStatus(Integer status, Long id) throws DisableSetmealDishException {
        //判断套餐关联的果蔬是否全部为启售状态,如果有未启售果蔬,则提示"套餐内包含未启售果蔬，无法启售"
        //根据套餐id查询套餐果蔬信息,多表查询果蔬状态
        // todo 只有前端传过来的状态是起售才进行是否有停售果蔬的判断
        if (Objects.equals(status, StatusConstant.ENABLE)) {
            List<SetmealDish> setmealDishes = setmealDishMapper.selectDisableDish(id);
            if (setmealDishes != null && !setmealDishes.isEmpty()) {
                //如果有未启售果蔬,则提示"套餐内包含未启售果蔬，无法启售"
                throw new DisableSetmealDishException(MessageConstant.SETMEAL_ENABLE_FAILED);
            }
        }
        //业务实现:更新套餐状态
        setmealMapper.updateSetmealStatus(status, id);
    }
    /**
     * 根据id查询套餐信息,用于查询回显
     *
     * @param id
     * @return
     */

    @Override
    public SetmealVO getSetmealById(Long id) {


        //业务实现:根据id查询套餐信息
        Setmeal setmeal = setmealMapper.selectSetmealById(id);

        //封装套餐信息到vo对象
        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);//属性复制
        //取出套餐id
        Long setmealId = setmeal.getId();
        if (setmealId != null) {
            //根据套餐id查询套餐果蔬信息,多表查询套餐果蔬信息
            List<SetmealDish> setmealDishes = setmealDishMapper.selectSetmealDishBySetmealId(setmealId);
            //封装套餐果蔬信息到vo对象
            setmealVO.setSetmealDishes(setmealDishes);
        }


        return setmealVO;
    }

    /**
     * 更新套餐信息
     * @param setmealDTO
     */
    @Override
    public void updateSetmeal(SetmealDTO setmealDTO) {
        //创建用于更新的Setmeal对象
        Setmeal setmeal = new Setmeal().builder()
                .id(setmealDTO.getId())
                .name(setmealDTO.getName())
                .categoryId(setmealDTO.getCategoryId())
                .status(setmealDTO.getStatus())
                .image(setmealDTO.getImage())
                .description(setmealDTO.getDescription())
                .price(setmealDTO.getPrice())
                .build();
        //创建用于修改套餐果蔬关联表的实体类列表
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        //业务实现:修改套餐信息
        setmealMapper.updateSetmeal(setmeal);
        //业务实现:删除原有套餐果蔬信息
        setmealDishMapper.deleteSetmealDishBySetmealId(setmeal.getId());
        //如果有套餐果蔬信息,插入新套餐果蔬信息
        if (setmealDishes != null && setmealDishes.size() > 0) {
            //设置补充套餐果蔬信息的setmealId属性
            setmealDishes.forEach(setmealDish -> {
                setmealDish.setSetmealId(setmeal.getId());
            });
            //业务实现:插入新套餐果蔬信息
            setmealDishMapper.insertSetmealDishes(setmealDishes);
        }
    }

    /**
     * 条件查询
     * @param setmeal
     * @return
     */
    @Override
    public List<Setmeal> listSetmeal(Setmeal setmeal) {
        List<Setmeal> list = setmealMapper.listForSetmeal(setmeal);
        log.info("list: " + list);
        return list;
    }

    /**
     * 根据id查询果蔬选项
     * @param id
     * @return
     */
    @Override
    public List<DishItemVO> getDishItemById(Long id) {
        return setmealMapper.getDishItemBySetmealId(id);
    }


}




